#include "stdafx.h"
#include "stream/streambuf.hpp"

namespace JHCPP
{
	namespace stream
	{	
		//////////////////////////////////////////////////////////////////
		//CMemoryIOS
		//////////////////////////////////////////////////////////////////
		CMemoryIOS::CMemoryIOS(char* pBuffer, std::streamsize bufferSize)
		: m_buf(pBuffer, bufferSize)
		{

		}

		CMemoryIOS::~CMemoryIOS()
		{

		}

		MemoryStreamBuf *CMemoryIOS::rdbuf()
		{
			return &m_buf;
		}


		//////////////////////////////////////////////////////////////////
		//CMemoryInputStream
		//////////////////////////////////////////////////////////////////
		CMemoryInputStream::CMemoryInputStream(const char* pBuffer, std::streamsize bufferSize)
		: CMemoryIOS(const_cast<char*>(pBuffer), bufferSize), 
		std::istream(&m_buf)
		{
		}

		CMemoryInputStream::~CMemoryInputStream()
		{
		}


		//////////////////////////////////////////////////////////////////
		//CMemoryOutputStream
		//////////////////////////////////////////////////////////////////
		CMemoryOutputStream::CMemoryOutputStream(char* pBuffer, std::streamsize bufferSize)
		: CMemoryIOS(pBuffer, bufferSize), 
			std::ostream(&m_buf)
		{
		}

		CMemoryOutputStream::~CMemoryOutputStream()
		{
		}

		std::streamsize CMemoryOutputStream::charsWritten() const
		{
			return m_buf.charsWritten();
		}


		CCountingStreamBuf::CCountingStreamBuf()
		: m_pIstr(0), 
		m_pOstr(0), 
		m_chars(0), 
		m_lines(0), 
		m_pos(0)
		{
		}

		CCountingStreamBuf::CCountingStreamBuf(std::istream& istr)
		: m_pIstr(&istr), 
		m_pOstr(0), 
		m_chars(0), 
		m_lines(0), 
		m_pos(0)
		{
		}

		CCountingStreamBuf::CCountingStreamBuf(std::ostream& ostr)
		: m_pIstr(0), 
		m_pOstr(&ostr), 
		m_chars(0), 
		m_lines(0), 
		m_pos(0)
		{
		}

		CCountingStreamBuf::~CCountingStreamBuf()
		{
		}

		int CCountingStreamBuf::chars() const
		{
			return m_chars;
		}

		int CCountingStreamBuf::lines() const
		{
			return m_lines;
		}

		int CCountingStreamBuf::pos() const
		{
			return m_pos;
		}

		void CCountingStreamBuf::reset()
		{
			m_chars = 0;
			m_lines = 0;
			m_pos   = 0;
		}

		void CCountingStreamBuf::setCurrentLineNumber(int line)
		{
			m_lines = line;
		}

		int CCountingStreamBuf::getCurrentLineNumber() const
		{
			return m_lines;
		}

		void CCountingStreamBuf::addChars(int chars)
		{
			m_chars += chars;
		}

		void CCountingStreamBuf::addLines(int lines)
		{
			m_lines += lines;
		}

		void CCountingStreamBuf::addPos(int pos)
		{
			m_pos += pos;
		}

		int CCountingStreamBuf::readFromDevice()
		{
			if (m_pIstr)
			{
				int c = m_pIstr->get();
				if (c != -1)
				{
					++m_chars;
					if (m_pos++ == 0) ++m_lines;
					if (c == '\n') m_pos = 0;
				}
				return c;
			}
			return -1;
		}

		int CCountingStreamBuf::writeToDevice(char c)
		{
			++m_chars;
			if (m_pos++ == 0) ++m_lines;
			if (c == '\n') m_pos = 0;
			if (m_pOstr) m_pOstr->put(c);
			return charToInt(c);
		}


		CCountingIOS::CCountingIOS()
		{
		}

		CCountingIOS::CCountingIOS(std::istream& istr) : m_buf(istr)
		{
		}

		CCountingIOS::CCountingIOS(std::ostream& ostr) : m_buf(ostr)
		{
		}

		CCountingIOS::~CCountingIOS()
		{
		}

		int CCountingIOS::chars() const
		{
			return m_buf.chars();
		}

		int CCountingIOS::lines() const
		{
			return m_buf.lines();
		}

		int CCountingIOS::pos() const
		{
			return m_buf.pos();
		}

		void CCountingIOS::setCurrentLineNumber(int line)
		{
			m_buf.setCurrentLineNumber(line);
		}

		int CCountingIOS::getCurrentLineNumber() const
		{
			return m_buf.getCurrentLineNumber();
		}

		void CCountingIOS::reset()
		{
			m_buf.reset();
		}

		void CCountingIOS::addChars(int chars)
		{
			m_buf.addChars(chars);
		}

		void CCountingIOS::addLines(int lines)
		{
			m_buf.addLines(lines);
		}

		void CCountingIOS::addPos(int pos)
		{
			m_buf.addPos(pos);
		}

		CCountingStreamBuf* CCountingIOS::rdbuf()
		{
			return &m_buf;
		}


		CCountingInputStream::CCountingInputStream(std::istream& istr) : CCountingIOS(istr), std::istream(&m_buf)
		{
		}

		CCountingInputStream::~CCountingInputStream()
		{
		}


		CCountingOutputStream::CCountingOutputStream(): std::ostream(&m_buf)
		{
		}

		CCountingOutputStream::CCountingOutputStream(std::ostream& ostr) : CCountingIOS(ostr), std::ostream(&m_buf)
		{
		}

		CCountingOutputStream::~CCountingOutputStream()
		{
		}


		CNullStreamBuf::CNullStreamBuf()
		{
		}

		CNullStreamBuf::~CNullStreamBuf()
		{
		}

		int CNullStreamBuf::readFromDevice()
		{
			return -1;
		}

		int CNullStreamBuf::writeToDevice(char c)
		{
			return charToInt(c);
		}


		CNullIOS::CNullIOS()
		{
			
		}

		CNullIOS::~CNullIOS()
		{
		}


		CNullInputStream::CNullInputStream(): std::istream(&m_buf)
		{
		}

		CNullInputStream::~CNullInputStream()
		{
		}


		CNullOutputStream::CNullOutputStream(): std::ostream(&m_buf)
		{
		}

		CNullOutputStream::~CNullOutputStream()
		{
		}
	}//end of namespace stream
}//end of namespace JHCPP
